/*
 * Copyright (c) 2011 Sapienza University of Rome.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of the Sapienza University of Rome nor the names of
 *   its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SAPIENZA
 * UNIVERSITY OF ROME OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * @author Ugo Colesanti <colesanti@dis.uniroma1.it>
 * @version 1.01 (October 10, 2011)
 *
 */

#ifndef MANAGER_H
#define MANAGER_H

enum{
	DEFAULT_WAKEUP_INTERVAL = 60 , //60 seconds

	AM_DATA_MSG = 0x95, // Data message for the ManagerC component
	AM_LPL_SYNC_MSG = 0x97,


	LPLMSG_SYNC_REQUEST = 0x00,
	LPLMSG_SYNC_REPLY = 0x01,
	LPLMSG_BROADCAST_RESET = 0x04,
	LPLMSG_UNICAST_RESET = 0x05,

	IN_SYNC = 0x80,

	// protocol state: nodes
	PROTOSTATE_GUARDTIME = 0x00 | IN_SYNC ,
	PROTOSTATE_CTPTREESETUP = 0x01 | IN_SYNC,
	PROTOSTATE_PREPARETOSLEEP = 0x03 | IN_SYNC,
	PROTOSTATE_SLEEP = 0x04 | IN_SYNC,
	PROTOSTATE_SYNC_RESP_SENDING = 0x05 | IN_SYNC , // can send only if I'm in_sync with 100% duty cycle

	// protocol state: sink
	ROOTSTATE_ACTIVE = 0x07 | IN_SYNC,
	ROOTSTATE_PAUSED = 0x08 | IN_SYNC,
	ROOTSTATE_GT = 0x09 | IN_SYNC,

	////////// MACRO_OUT_OF_SYNC states
	PROTOSTATE_LPL_TRY_RESYNC = 0x02 & ~IN_SYNC,
	PROTOSTATE_LPL_SYNC_REQ_SENDING = 0x03 & ~IN_SYNC , // send a sync request -> I'm out_of sync
	PROTOSTATE_LPL_SYNC_RESP_WAITING = 0x04 & ~IN_SYNC, // wait for a sync -> I'm out_of_sync


	// Trickle-like timer (for LplManager)
	MIN_INTERVAL = 30720UL,
	MAX_INTERVAL = 1843200UL,

	// Max backoff during Lpl operations
	LPL_RESPONSE_BACKOFF = 1024,

	// Maximum length for RI and DCI. Increase it if the network is large.
	CTPTREESETUP_TIMEOUT = 2048,
	PREPARETOSLEEP_TIMEOUT = 2048,


	// Debug values, to be deleted... -----------------------------------
	GENERALTIMERFIRED 				= 1,
	GENERALTIMERFIRED_CTR 			= 2,
	GENERALTIMERFIRED_GT 			= 3,
	GENERALTIMERFIRED_TTNF 			= 4,
	PROTOTIMERFIRED_STATE 			= 5,
	PROTOTIMERFIRED_RI 				= 6,
	PROTOTIMERFIRED_PTSI			= 7,
	PROTOTIMERFIRED_OOSCOUNTER 		= 8,
	PROTOTIMERFIRED_ROOTRESYNC 		= 9,
	PROTOTIMERFIRED_ROOTNORESYNC 	= 10,
	RESYNC_EVENT					= 11,
	RESYNC_NWUT 					= 12,
	RESYNC_REMAINING 				= 13,
	RECEIVEDRESYNC_RX 				= 14,
	RECEIVEDRESYNC_RI 				= 15,
	RECEIVEDRESYNC_PTSI 			= 16,
	RECEIVEDRESYNC_SKIP 			= 17,
	SENDPACKET_TTR 					= 18,
	FATALPROBLEM_ERRCODE 			= 19,
	GOTOSLEEP_MSGSENT 				= 20,
	RX_SYNC_BUT_WAS_ALREADY			= 21,

	FE_BOOT_ROUTINGNOSTART					= 1,
	FE_SENDDONE_MSGNOTINBUFFER				= 2,
	FE_PSS_ROUTINGNOSTART					= 3,
	FE_RSP_ROUTINGNOSTART					= 4,
	FE_GENERALTIMER_UNKOWNSTATE				= 5,
	FE_PROTOTIMER_CTS_ROUTINGNOSTOP			= 6,
	FE_PROTOTIMER_RSA_ROUTINGNOSTOP			= 7,
	FE_PROTOTIMER_UNKOWNSTATE				= 8,
	FE_SETPARENTNEXTWAKEUPTIME				= 9,
	FE_STATERESPONSESENDDONE_UNKOWNSTATE	= 10,
	FE_SYNCRESPONSESENDDONE_UNKOWNSTATE		= 11,
	FE_SYNCREQUESTSENDDONE_UNKNWOWNSTATE	= 12,
	FE_RESYNCEVNT_UNKOWNSTATE				= 13,
	FE_RECEIVEDSYNC_UNKOWNSTATE				= 14,
	FE_GOTOSLEEP_ROUTINGNOSTOP				= 15,
	// -----------------------------------------------------------------

};

// Internal structure for ManagerC component: keeps the state of the Manager.
typedef nx_struct managerStateMsg{
	nx_uint8_t proto_state ; // protocol state of the node
	nx_uint8_t previous_state ;
	nx_uint32_t nextWakeUpTime ; // next wake up scheduled (timestamp)
}managerStateMsg_t ;

// Footer that the manager append at each data message
typedef nx_struct rm_stat{
	nx_uint16_t ttr ;
}rm_stat_t ;

// Schedule information struct, it is used both, to keep the state of the manager and to send schedule info.
typedef nx_struct schedule_info{
	nx_uint16_t current_sampling_period  ;		// 2
	nx_uint16_t current_schedule_gt ;			// 2
	nx_uint16_t current_schedule_ri ;			// 2
	nx_uint16_t current_schedule_dci ;			// 2
	nx_uint8_t current_schedule_skip ;			// 1
	nx_uint16_t next_sampling_period ;			// 2
	nx_uint32_t time_to_next_sampling_period ;  // 4
	nx_uint32_t next_sampling_period_fired ;	// 4
}schedule_info_t ;

// Lpl message. It is used for both, synchronize an out of sync node and to propagate reboot.
typedef nx_struct lplMsg{
	nx_uint8_t type ;
	nx_uint16_t address ;
	schedule_info_t schedule_info ;
}lplMsg_t ;


#endif
